package eu.catengine.graphic;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import eu.catengine.common.iface.IDisposable;
import eu.catengine.primitive.Point;
import eu.catengine.primitive.Size;

/**
 * Klasa przechowująca dane dotyczące regionów tekstur.
 * 
 * @author mbienkowski
 */
public class TextureRegion implements IDisposable
{
    Size mRegionSize;
    float mRegionCoords[];
    FloatBuffer mTextureBuffer;
    ByteBuffer mByteBuffer;
    Size mSize;

    /**
     * Konstruktor.
     * 
     * @param regionCoords
     *            <code>float[]</code> Tablica wierzchołków dla regionu
     *            tekstury.
     */
    public TextureRegion(float[] regionCoords)
    {
	mRegionCoords = regionCoords;

	mByteBuffer = ByteBuffer.allocateDirect(32);
	mByteBuffer.order(ByteOrder.nativeOrder());

	mTextureBuffer = mByteBuffer.asFloatBuffer();
	mTextureBuffer.put(mRegionCoords);
	mTextureBuffer.position(0);
    }

    /**
     * Konstruktor.
     * 
     * @param point
     *            <code>Point</code> Punkt zaczepienia regionu.
     * @param regionSize
     *            <code>Size</code> Rozmiar regionu.
     * @param textureSize
     *            <code>Size</code> Rozmiar tekstury.
     */
    public TextureRegion(Point point, Size regionSize, Size textureSize)
    {
	this.mRegionSize = regionSize;

	float x = point.x;
	float y = point.y;
	float width = regionSize.width;
	float height = regionSize.height;
	float texWidth = textureSize.width;
	float texHeight = textureSize.height;

	mRegionCoords = new float[] { x / texWidth, (y + height) / texHeight, // top
									      // left
									      // (V2)
		x / texWidth, y / texHeight, // bottom left (V1)
		(x + width) / texWidth, (y + height) / texHeight, // top right
								  // (V4)
		(x + width) / texWidth, y / texHeight // bottom right (V3)
	};

	mByteBuffer = ByteBuffer.allocateDirect(32);
	mByteBuffer.order(ByteOrder.nativeOrder());

	mTextureBuffer = mByteBuffer.asFloatBuffer();
	mTextureBuffer.put(mRegionCoords);
	mTextureBuffer.position(0);
    }

    /**
     * Aktualizuje bufor regionu.
     */
    public void updateBuffer()
    {
	mTextureBuffer.clear();
	mTextureBuffer = mByteBuffer.asFloatBuffer();
	mTextureBuffer.put(mRegionCoords);
	mTextureBuffer.position(0);
    }

    /**
     * Zwraca rozmiar regionu.
     */
    public Size getSize()
    {
	return mRegionSize;
    }

    /**
     * Zwraca szerokośc regionu.
     */
    public float getWidth()
    {
	return mRegionSize.width;
    }

    /**
     * Zwraca wysokość regionu.
     */
    public float getHeight()
    {
	return mRegionSize.height;
    }

    /**
     * Zwraca bufor tekstury dla regionu.
     */
    public FloatBuffer getTextureBuffer()
    {
	return mTextureBuffer;
    }

    @Override
    public void dispose()
    {
	mByteBuffer.clear();
	mTextureBuffer.clear();

	mRegionCoords = null;
	mRegionSize = null;
	mTextureBuffer = null;
	mByteBuffer = null;
	mSize = null;
    }
}
